﻿using System;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.ServiceModel.Web;

namespace MyWcfRestLib.Files
{
    partial class FileTransfer : IFileTransfer
    {
        private ChunkUploadInfo CurrentChunkUpload;
        private ServiceInfo FileServiceInfo = new ServiceInfo() { MaxMessageSize = Constant.MaxMessageSize, BaseFilePath = System.IO.Path.Combine(System.Environment.CurrentDirectory, "files") };

        private NameValueCollection QueryParameters { get { return WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters; } }

        private void ClearIncompletedChunk(ChunkUploadInfo chunkInfo)
        {
            if (!string.IsNullOrEmpty(chunkInfo.UploadID))
            {
                string tempFile = GetTempFileName(chunkInfo);
                if (File.Exists(tempFile))
                {
                    File.Delete(GetTempFileName(chunkInfo));
                }
            }
            InitChunkInfo(chunkInfo);
        }

        private ChunkUploadInfo CreateNewChunkInfo()
        {
            ChunkUploadInfo chunkInfo = new ChunkUploadInfo();
            InitChunkInfo(chunkInfo);
            return chunkInfo;
        }

        private void InitChunkInfo(ChunkUploadInfo chunkInfo)
        {
            chunkInfo.UploadID = Guid.NewGuid().ToString("N");
            chunkInfo.ExpireTime = (DateTime.UtcNow + TimeSpan.FromHours(24)).ToString(Constant.TimeStringFormat);
            chunkInfo.Offset = 0;
            chunkInfo.RootFolder = "default";
            chunkInfo.TempFolder = ".tmp";
            chunkInfo.TempName = chunkInfo.UploadID + ".tmp";
        }

        private string GetTempFileName(ChunkUploadInfo chunkInfo)
        {
            return Path.Combine(new string[] { FileServiceInfo.BaseFilePath, chunkInfo.TempFolder, chunkInfo.TempName });
        }

        private MetadataInfo GetMetadata(string root, string relativePath, bool willListContent)
        {
            if (string.IsNullOrWhiteSpace(root))
            {
                return null;
            }

            string path = Path.Combine(new string[] { FileServiceInfo.BaseFilePath, root, (null == relativePath) ? "" : relativePath });

            MetadataInfo info = new MetadataInfo { Root = root, RelativePath = relativePath, RealPath = path };

            if (Directory.Exists(path))
            {
                info.IsDir = true;
                DirectoryInfo dir = new DirectoryInfo(path);
                info.ModifiedTime = dir.LastWriteTimeUtc.ToString(Constant.TimeStringFormat);
                if (willListContent)
                {
                    info.Contents = GetContent(info);
                }
            }
            else if (File.Exists(path))
            {
                info.IsDir = false;
                FileInfo file = new FileInfo(path);
                info.FileSize = file.Length;
                info.ModifiedTime = file.LastWriteTimeUtc.ToString(Constant.TimeStringFormat);
            }
            else
            {
                return null;
            }



            return info;
        }

        private MetadataInfo[] GetContent(MetadataInfo folder)
        {
            Debug.Assert(Directory.Exists(folder.RealPath));

            if (!folder.IsDir)
                return null;

            DirectoryInfo dir = new DirectoryInfo(folder.RealPath);
            string path = (null == folder.RelativePath) ? "" : folder.RelativePath;
            var contents = dir.GetDirectories().Select(item => GetMetadata(folder.Root, Path.Combine(path, item.Name), false))
                .Concat(dir.GetFiles().Select(item => GetMetadata(folder.Root, Path.Combine(path, item.Name), false)));
            return contents.ToArray();

        }
    }
}
